Skip to content

[c++] Avoid redundant copies during row type resolution - #4246

Merged
fresh-borzoni merged 2 commits into
apache:mainfrom
naivedogger:bugfix/issue-4239-borrow-row-resolution
Sep 17, 2026
Merged

fresh-borzoni merged 2 commits into
apache:mainfrom
naivedogger:bugfix/issue-4239-borrow-row-resolution

Conversation

@naivedogger

Copy link
Copy Markdown
Contributor

Summary

Test Plan

  • 4 regression tests passed.
  • Cargo formatting and Clippy checks passed.
  • Full Maven verification was blocked by an unrelated untracked file's license header.

🤖 AI-assisted changes - reviewed by human developer

Borrow unchanged STRING and BYTES values from the input row while preserving type conversions and validation. Add regression tests for borrowed storage, mixed conversions, nested rows, and invalid values.

Fixes apache#4239

@fresh-borzoni fresh-borzoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naivedogger LGTM overall 👍
One question for a follow-up: when no column actually needs converting, we still build a whole second row. Could we skip resolve_row_types entirely in that case, as #4239 also suggested?

resolve_row_types now returns the input row borrowed when no column
needs converting, building a second row only for actual conversions or
for padding short upsert/delete rows to full schema width. The lookup
and prefix-lookup paths compact and resolve in one pass via the new
resolve_dense_row_types, which likewise skips the rebuild for
already-dense rows. Addresses the follow-up from the review of apache#4246.
@naivedogger

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Pushed a follow-up commit that does this. resolve_row_types now checks whether any column would actually change, i.e. an Int32 targeted at TinyInt or SmallInt, or a String targeted at Decimal, including inside nested rows. When nothing needs converting it returns the input row borrowed and no second row is built. Upsert and delete still pad short rows to full schema width, but a full-width row that needs no conversion now goes straight to the core writer.

The lookup paths got the same treatment: they compact and resolve in one pass, and when the PK or prefix values are already at dense positions with nothing to convert, the input row is used as-is. Validation behavior is unchanged, and the fast paths are covered by new tests.

@fresh-borzoni fresh-borzoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naivedogger Thank you, LGTM 👍

@fresh-borzoni
fresh-borzoni merged commit 6fe8367 into apache:main Sep 17, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[c++] Avoid redundant STRING and BYTES copies during row type resolution

2 participants